package scr.hotel;

import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;

import scr.hibernate.InitSessionFactory;

public class Reserva {
	private int id;
	private Date inicioReserva;
	private Date fimReserva;
	private String numeroDoQuarto;
	private int numeroReserva;
	private int idCliente;
	private String cpfCliente;
	
	
	public Reserva(){}

	public Reserva(Date inicio, Date fim){
		Random random = new Random(System.currentTimeMillis());
		int i = random.nextInt(10000000);
		numeroReserva = i;
	}

	public String getCpfCliente() {
		return cpfCliente;
	}

	public void setCpfCliente(String cpfCliente) {
		this.cpfCliente = cpfCliente;
	}

	public int getIdCliente() {
		return idCliente;
	}
	public void setIdCliente(int idCliente) {
		this.idCliente = idCliente;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}

	public int getNumeroReserva() {
		return numeroReserva;
	}
	public void setNumeroReserva(int numeroReserva) {
		this.numeroReserva = numeroReserva;
	}

	public String getNumeroDoQuarto() {
		return numeroDoQuarto;
	}	
	public void setNumeroDoQuarto(String numeroDoQuarto) {
		this.numeroDoQuarto = numeroDoQuarto;
	}

	public Date getFimReserva() {
		return fimReserva;
	}	
	public void setFimReserva(Date fimReserva) {
		this.fimReserva = fimReserva;
	}

	public Date getInicioReserva() {
		return inicioReserva;
	}
	public void setInicioReserva(Date inicioReserva) {
		this.inicioReserva = inicioReserva;
	}

	public static boolean criarReserva(Reserva reserva, Quarto quarto, Cliente cliente) 
	{
		Transaction tx = null;
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		reserva.setNumeroDoQuarto(quarto.getNumero());
		reserva.setCpfCliente(cliente.getCpf());
		try {
			tx = session.beginTransaction();
			session.save(reserva);
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null && tx.isActive())
				tx.rollback();

			return false;
		}
		
	return true;

	}

	public static boolean cancelarReserva(Reserva reserva)
	{
		Transaction tx = null;
		Session session = InitSessionFactory.getInstance().getCurrentSession();
		try {
			tx = session.beginTransaction();
			session.delete(reserva);

			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null && tx.isActive())
				tx.rollback();
			return false;
		}
		return true;
	}


	/*
	 * Retorna uma lista encadeada com todos os quartos do perfil procurado,
	 * que estarao disponiveis para reserva na determinada epoca.
	 */
	public static LinkedList listarDisponiveis(TipoDeQuarto perfil, Reserva reserva)
	{
		// todos os quartos do hotel com o derminado padrao
		LinkedList busca = Quarto.buscaQuarto(perfil); 
		// todas as reservas
		LinkedList listaReservas = Reserva.listarReservas(); 
		if (listaReservas == null) return null;
		Date inicioNova = reserva.getInicioReserva();
		Date fimNova = reserva.getFimReserva();
		Quarto quarto;

		int decremento = 0;
		for(int i=0; (i < busca.size()-decremento)&& !(busca.isEmpty()); i++ )
		{
			quarto  = (Quarto) busca.get(i);
			for(int j = 0; j < listaReservas.size(); j++)
			{
				Reserva reservaExistente = (Reserva) listaReservas.get(j);
				Date inicioExistente = reservaExistente.getInicioReserva();
				Date fimExistente = reservaExistente.getFimReserva();
				
				if(quarto.getNumero().equals(reservaExistente.getNumeroDoQuarto()))
				{

					if( inicioNova.after(fimExistente) )  continue;
					
					if( fimNova.before(inicioExistente) ) continue;

					
					if ( ( ( inicioNova.before(inicioExistente)&&(!inicioNova.equals(inicioExistente) ) )
							&& fimNova.before(inicioExistente)) ) continue;
					
					if ( ( inicioNova.after(fimExistente) ) &&  
							( fimNova.after(fimExistente)&& (!fimNova.equals(fimExistente) ) ) )  continue;
					
					
					if ( ( inicioNova.before(fimExistente) && fimNova.after(fimExistente) ) ) continue;

					if(i<0) return busca;
					busca.remove(i);
					i--;
					decremento++;
				}
			}
		}
		return busca;
	}


	public static LinkedList reservasPorQuarto(String numero)
	{
		LinkedList reservas = (LinkedList)Reserva.listarReservas();

		for(int i=0; i < reservas.size(); i++ )
		{
			Reserva elemento = (Reserva)reservas.get(i);

			if ( elemento.numeroDoQuarto.equalsIgnoreCase(numero) == false )
			{
				reservas.remove(i);
				i--;
			}

		}
		return reservas;
	}

	public static LinkedList listarReservas()
	{
		Transaction tx = null;
		Session sessao = InitSessionFactory.getInstance().getCurrentSession();
		List reservas = null;
		try {
			tx = sessao.beginTransaction();
			reservas = sessao.createCriteria(Reserva.class)
			.addOrder( Order.asc("numeroDoQuarto") )
			.list();

			tx.commit();
	
		} catch (HibernateException e) {
			e.printStackTrace();
		}

		
		LinkedList linkedList = new LinkedList(reservas);
		return linkedList;

	}

	public static LinkedList reservasPorCliente(Cliente cliente)
	{
		LinkedList reservas = (LinkedList)Reserva.listarReservas();
		String cpf = cliente.getCpf();

		for(int i=0; i < reservas.size(); i++ )
		{
			Reserva elemento = (Reserva)reservas.get(i);
			if ( elemento.numeroDoQuarto.equalsIgnoreCase(cpf) == false )
			{
				reservas.remove(i);
				i--;
			}
		}
		return reservas;
	}

	public String toString(){
		return "Inicio: " + inicioReserva + " Fim: " + fimReserva + " Numero: " + numeroDoQuarto;
	}

}